package com.lagou.edu.Spring;

import com.lagou.edu.zdy.config.Service;
import com.lagou.edu.zdy.util.ClassUtil;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Bean创建工厂
 */
public class ApplicationContext {

    private static final char PACKAGE_SEPARATOR = '.';

    /** 项目启动主类 */
    public static Class<?> mainApplicationClass;
    /** 项目启动基础包路径 */
    public static String basePackage;
    /** 获取包路径下的所有类 */
    private static List<Class<?>> classes;
    /** ioc */
    public static ConcurrentHashMap<String,Object> ioc = new ConcurrentHashMap<>();


    /**
     * 创建容器
     */
    public static void createContext() throws IllegalAccessException {
        //获取项目的主启动类
        mainApplicationClass = deduceMainApplicationClass();

        //获取扫描包路径
        Package aPackage = mainApplicationClass.getPackage();
        basePackage =  aPackage.getName();

        //扫描注解：@Service , 构建ioc容器
        classes = ClassUtil.getClasses(basePackage);
        BuildIoc();
        System.out.println(ioc.size());
    }


    /**
     * 构建ioc容器
     * @throws IllegalAccessException
     */
    private static void BuildIoc() throws IllegalAccessException {
        for (Class<?> aClass : classes) {
            if (aClass.isAnnotationPresent(Service.class)) {

                //获取接口的class作为key，当前类对象作为值
                try {
                    Class<?> interfaceClass = null;
                    Class<?>[] interfaces = aClass.getInterfaces();
                    for (Class<?> anInterface : interfaces) {
                        String interfaceName = anInterface.getSimpleName();
                        String simpleName = aClass.getName();
                        boolean contains = simpleName.contains(interfaceName);
                        if (contains) {
                            interfaceClass=anInterface;
                            break;
                        }
                    }
                    if(interfaceClass!=null) {
                        ioc.put(interfaceClass.getName(), aClass.newInstance());
                    }
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据类名获取权限定类名
     * @param className
     */
    public static String getFullClassName(String className){
        for (Class<?> aClass : classes) {
            if(aClass.getSimpleName().equals(className)){
                return aClass.getName();
            }
        }
        return null;
    }
    /**
     * 获取项目的主启动类
     * @return
     */
    private static Class<?> deduceMainApplicationClass() {
        try {
            StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
            for (StackTraceElement stackTraceElement : stackTrace) {
                if (stackTraceElement.getMethodName().equals("main")) {
                    System.out.println("启动类名称："+stackTraceElement.getClassName());
                    return Class.forName(stackTraceElement.getClassName());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}
